package com.saianfu.flowable

import com.saianfu.flowable.attendence.*

import org.flowable.engine.*

import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration

import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

internal class FlowableExAttendenceTest {
    lateinit var cfg: StandaloneProcessEngineConfiguration
    lateinit var processEngine: ProcessEngine
    lateinit var repositoryService: RepositoryService
    lateinit var runtimeService: RuntimeService
    lateinit var historyService: HistoryService
    lateinit var taskService: TaskService


    @BeforeEach
    fun setUp() {
        cfg = StandaloneProcessEngineConfiguration().also {
            it.jdbcPassword = "123456"
            it.jdbcUsername = "root"
            it.jdbcUrl = "jdbc:mysql://127.0.0.1:3306/flowable?" +
                    "useUnicode=true&characterEncoding=utf-8" +
                    "&useSSL=true" +
                    "&serverTimezone=UTC" +
                    "&nullCatalogMeansCurrent=true" +
                    "&allowMultiQueries=true"
            it.jdbcDriver = "com.mysql.cj.jdbc.Driver"
        }

        processEngine = cfg.buildProcessEngine()
        repositoryService = processEngine.repositoryService
        runtimeService = processEngine.runtimeService
        historyService = processEngine.historyService
        taskService = processEngine.taskService
//        val deployment = repositoryService.createDeployment()
//                .addClasspathResource("processes//Approve003.bpmn20.xml")
//                .deploy()
    }


    @Test
    fun deploy() {
//        FlowableEx.deploy(repositoryService, "processes//Approve003.bpmn20.xml")
    }

    @Test
    fun testAttendance() {
        //1、创建请假流程
        //2、HR预审
        //3、科室负责人审核
        //4、部门负责人审核
        //5、分管领导审核
        //6、副总经理审核
        //7、总经理审核
    }


    @Test
    fun startProcessInstanceByKey() {
        val employeeLevel = EmployeeLevel.DeputyManager
        val leaveType = LeaveType.AnnualLeave
        val set = ApplyConditionUtil.getApproveLayerList(employeeLevel, leaveType, 0.5f)
        val variables = mutableMapOf<String, Any>()
        variables["_FLOWABLE_SKIP_EXPRESSION_ENABLED"] = true


        //初始设置审核结果都为-1，则流程会停止在下个节点上
        AttendanceFlowContent.nodeResultVariableNameList.forEachIndexed { index, variableName ->
            variables[variableName] = -1
        }
        //默认全部跳过节点
        AttendanceFlowContent.skipVariableNameList.forEachIndexed { index, variableName ->
            variables[variableName] = true
        }
        //通过计算得到三个审批人
        val assigneeList = mutableListOf<String>("hrman", "officeman", "deptman")
        assigneeList.forEachIndexed { index, nodeAssignee ->
            val variableName = AttendanceFlowContent.nodeAssigneeVariableNameList[index]
            val skipVariableName = AttendanceFlowContent.skipVariableNameList[index]
            variables[variableName] = nodeAssignee
            variables[skipVariableName] = false
        }

        val pi = FlowableEx.startProcessInstanceByKey(runtimeService,
                "AttendanceFlow001", variables = variables)
        println(pi.processInstanceId)

    }


    @Test
    fun node1() {
        val currentUser = "hrman"
        approve(currentUser)
    }

    @Test
    fun node2() {
        val currentUser = "officeman"
        approve(currentUser)
    }

    @Test
    fun node3() {
        val currentUser = "deptman"
        approve(currentUser)
    }

    private fun approve(currentUser: String) {
        val list = FlowableEx.taskByCondition(taskService, mapOf(), currentUser, 2, 0, 100)
        list.forEach {
            println("${it.id} -- ${it.processInstanceId} -- ${it.createTime}")
            val skipList = MutableList(AttendanceFlowContent.maxNodeCount) { true }
            val assigneeList = MutableList(AttendanceFlowContent.maxNodeCount) { "" }

            FlowableEx.listVariableByTaskId(taskService, it.id).forEach { t, u ->
                println("$t:$u")
                AttendanceFlowContent.nodeAssigneeVariableNameList.forEachIndexed { index, s ->
                    if (t == s) {
                        assigneeList[index] = u as String
                    }
                }
                AttendanceFlowContent.skipVariableNameList.forEachIndexed { index, s ->
                    if (t == s) {
                        skipList[index] = u as Boolean
                    }
                }
            }
            //当前流程的审核层级总数
            val approveLayerCount = skipList.count {
                !it
            }
            //当前审核人属于第几个审核层级
            val idx = assigneeList.indexOfFirst { name -> name == currentUser }

            if (idx + 1 == approveLayerCount) {
                //若审核通过，当前是最后一层审批
                println("当前是最后一层审批")
            }

            val variableCurrent = mutableMapOf<String, Any>()
            //设置结果为通过
            variableCurrent[AttendanceFlowContent.nodeResultVariableNameList[idx]] = 1
            FlowableEx.completeTask(taskService, it.id, variableCurrent)

        }
    }

    @Test
    fun history() {
        val currentUser = "hrman"
        historyService.createHistoricActivityInstanceQuery().taskAssignee(currentUser)
                .orderByHistoricActivityInstanceStartTime()
                .desc()
                .list()
                .forEachIndexed { index, historicActivityInstance ->
                    println(historicActivityInstance.processInstanceId)
                    historyService.createHistoricVariableInstanceQuery()
                            .processInstanceId(historicActivityInstance.processInstanceId)
                            .list()
                            .forEachIndexed { index, historicVariableInstance ->
                                println(historicVariableInstance.variableName
                                        + "---" + historicVariableInstance.value)
                            }
                }
    }


    @AfterEach
    fun tearDown() {
    }
}